package com.sophossystems.client.asmon.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;


import com.sophossystems.client.asmon.dao.ClienteDao;
import com.sophossystems.client.asmon.dao.ClientePMoralesDao;
import com.sophossystems.client.asmon.dao.ClientePersonasFisicasDao;
import com.sophossystems.client.asmon.dao.DelegacionDao;
import com.sophossystems.client.asmon.dao.DireccionDao;
import com.sophossystems.client.asmon.dao.EstadosDao;
import com.sophossystems.client.asmon.dao.MunicipiosDao;
import com.sophossystems.client.asmon.dao.RutaDao;
import com.sophossystems.client.asmon.dao.TipoZonaDao;
import com.sophossystems.client.asmon.dao.ZonaDao;
import com.sophossystems.client.asmon.dto.DelegacionDTO;
import com.sophossystems.client.asmon.dto.EstadosDTO;
import com.sophossystems.client.asmon.dto.MunicipiosDTO;
import com.sophossystems.client.asmon.dto.RutaDTO;
import com.sophossystems.client.asmon.dto.RutaPkDTO;
import com.sophossystems.client.asmon.dto.TipoZonaDTO;
import com.sophossystems.client.asmon.dto.ZonaDTO;
import com.sophossystems.client.asmon.exceptions.BusinessException;
import com.sophossystems.client.asmon.service.RouteServices;

public class RouteServicesImpl implements RouteServices {
	private DireccionDao direccionDao;
	private ClientePMoralesDao personaMoralDao;
	private ClientePersonasFisicasDao personaFisicaDao;
	private ClienteDao clienteDao;
	private RutaDao rutaDao;
	private ZonaDao zonaDao;
	private MunicipiosDao municipiosDao;
	private DelegacionDao delegacionDao;
	private EstadosDao estadosDao;
	private TipoZonaDao tipoZonaDao;
	
	private static Logger logger = Logger.getLogger(RouteServicesImpl.class);

	@Override
	public List<RutaDTO> guardarRuta(List<RutaDTO> ruta) throws BusinessException {
		 List<RutaDTO> exito = new ArrayList<RutaDTO>();
		 List<RutaPkDTO> pk = new ArrayList<RutaPkDTO>();
//		 evalua si la lista contiene elementos.
		 if(ruta.size() > 0){
//			 recorre el listado de la ruta y lo inserta uno a uno, guardando el pk de cada registro
			 try {
				 for (RutaDTO rutaDto : ruta ) {
					 pk.add(rutaDao.insert(rutaDto));
				 	}
			} catch (Exception e) {
				logger.debug("Error guardarRuta, causa: " + e.getCause());
				throw new BusinessException("Error guardarRuta, causa: " + e.getCause());
			}
//			 llena un listado con pk de cada elemento de la lista que se inserto
			 try {
				 for (RutaPkDTO rutaPkDTO : pk) {
					exito.add(rutaDao.findByPrimaryKey(rutaPkDTO.getIdRuta()));
				}
				
			} catch (Exception e) {
				logger.debug("Error guardarRuta findById, causa: " + e.getCause());
				throw new BusinessException("Error guardarRuta findById, causa: " + e.getCause());
			}
		 }
		
		return exito;
	}

	@Override
	public List<RutaDTO> cerrarRuta(List<RutaDTO> ruta) throws BusinessException {
		List<RutaDTO> exito = new ArrayList<RutaDTO>();
		try {
			for (RutaDTO rutaDTO : ruta) {
				rutaDao.update(rutaDTO);
			}
		} catch (Exception e) {
			logger.debug("error al actualizar cerrarRuta, causa: " + e.getCause());
			throw new BusinessException("error al actualizar cerrarRuta, causa: " + e.getCause());
		}
		try {
			for (RutaDTO rutaDto : ruta) {
				exito.add(rutaDao.findByPrimaryKey(rutaDto.getCierreRuta()));
			}
		} catch (Exception e) {
			logger.debug("error al traer cerrarRuta , causa: " + e.getCause());
			throw new BusinessException("error al actualizar cerrarRuta, causa: " + e.getCause());
		}
		return exito;
	}

	@Override
	public String eliminarRuta(List<RutaDTO> ruta) throws BusinessException {
		String exito = null;
		RutaPkDTO pk = new RutaPkDTO();
		 try {
			for (RutaDTO rutaDTO : ruta) {
				pk.setIdRuta(rutaDTO.getIdRuta());
				rutaDao.delete(pk);
			}
			exito = "ok";
		} catch (Exception e) {
			 logger.debug("error al eliminar ruta, causa: " + e.getCause());
			 throw new BusinessException("error al eliminar ruta, causa: " + e.getCause());
		}
		return exito;
	}

	@Override
	public List<RutaDTO> buscarRutaCliente(int idCliente)
			throws BusinessException {
		List<RutaDTO> exito = null;
		try {
			exito = rutaDao.findByIdCliente(idCliente);
		} catch (Exception e) {
			 logger.debug("error al buscar ruta por cliente, causa: " + e.getCause());
			 throw new BusinessException("error al buscar ruta por cliente, causa: " + e.getCause());
		}
		return exito;
	}

	@Override
	public List<RutaDTO> buscarRutaMensajero(int idMensajero)
			throws BusinessException {
		List<RutaDTO> exito = null;
		try {
			exito = rutaDao.findByIdMensajero(idMensajero);
		} catch (Exception e) {
			 logger.debug("error al buscar ruta por mensajero, causa: " + e.getCause());
			 throw new BusinessException("error al buscar ruta por mensajero, causa: " + e.getCause());
		}
		return exito;
	}

	@Override
	public List<RutaDTO> buscarRutaZona(int idZona) throws BusinessException {
		List<RutaDTO> exito = null;
		try {
			exito = rutaDao.findByIdZona(idZona);
		} catch (Exception e) {
			 logger.debug("error al buscar ruta por cliente, causa: " + e.getCause());
			 throw new BusinessException("error al buscar ruta por cliente, causa: " + e.getCause());
		}
		return exito;
	}

	@Override
	public List<RutaDTO> buscarRutaDia(Date dia) throws BusinessException {
		List<RutaDTO> exito = null;
		if(dia != null){
			try {
				exito = rutaDao.findByDate(dia);
			} catch (Exception e) {
				logger.debug("Error buscarRutaDia, causa: " + e.getCause());
				throw new BusinessException("Error buscarRutaDia, causa: " + e.getCause());
			}
		}
		
		return exito;
	}

	@Override
	public List<RutaDTO> buscarRutaRangoFechas(Date fechaIni, Date fechaFin)
			throws BusinessException {
		List<RutaDTO> exito = null;
		try {
			exito = rutaDao.buscarRangoFecha(fechaIni, fechaFin);
		} catch (Exception e) {
			logger.debug("Error busqueda rango fechas, causa: " + e.getCause());
		}

		return exito;
	}
	
	@Override
	public List<RutaDTO> buscarRutaAbierta(int idStatus) throws BusinessException{
		List<RutaDTO> exito = null;
		try {
			exito = rutaDao.findByIdCierreRuta(idStatus);
		} catch (Exception e) {
			logger.debug("error en buscarRutaAbierta, causa: " +e.getCause());
			throw new BusinessException("error en buscarRutaAbierta, causa: " +e.getCause());
		}
		
		return exito;
	}
	
	@Override
	public List<EstadosDTO> estados() throws BusinessException {
		List<EstadosDTO> exito = null;
		try {
			exito = estadosDao.findAll();
		} catch (Exception e) {
			logger.debug("error al extrar los estados, causa: " + e.getCause());
		}
		return exito;
	}

	@Override
	public List<DelegacionDTO> delegacion() throws BusinessException {
		List<DelegacionDTO> exito = null;
		try {
			exito = delegacionDao.findAll();
		} catch (Exception e) {
			logger.debug("error al extrar las delegaciones, causa: " + e.getCause());
		}
		return exito;
	}

	@Override
	public List<TipoZonaDTO> tipoZona() throws BusinessException {
		List<TipoZonaDTO> exito = null;
		try {
			exito = tipoZonaDao.findAll();
		} catch (Exception e) {
			logger.debug("error al extrar las tipoZona, causa: " + e.getCause());
		}
		for (TipoZonaDTO tipoZonaDTO : exito) {
			System.out.println(tipoZonaDTO.getNombreZona());
		}
		return exito;
	}

	@Override
	public List<MunicipiosDTO> municipios() throws BusinessException {
		List<MunicipiosDTO> exito = null;
		try {
			exito = municipiosDao.findAll();
		} catch (Exception e) {
			logger.debug("error al extrar los municipios, causa: " + e.getCause());
		}
		return exito;
	}
	
	@Override
	public List<ZonaDTO> zona() throws BusinessException {
		List<ZonaDTO> exito = null;
		try {
			exito = zonaDao.findAll();
		} catch (Exception e) {
			logger.debug("error al extrar las Zona, causa: " + e.getCause());
		}
		return exito;
	}
	
	@Override
	public List<ZonaDTO> zona(int idZona) throws BusinessException {
		List<ZonaDTO> exito = null;
		try {
			exito = zonaDao.findByIdTipoZona(idZona);
		} catch (Exception e) {
			logger.debug("error al extrar las Zona, causa: " + e.getCause());
		}
		return exito;
	}
	

	/**
	 * @return the direccionDao
	 */
	public DireccionDao getDireccionDao() {
		return direccionDao;
	}

	/**
	 * @param direccionDao the direccionDao to set
	 */
	public void setDireccionDao(DireccionDao direccionDao) {
		this.direccionDao = direccionDao;
	}

	/**
	 * @return the personaMoralDao
	 */
	public ClientePMoralesDao getPersonaMoralDao() {
		return personaMoralDao;
	}

	/**
	 * @param personaMoralDao the personaMoralDao to set
	 */
	public void setPersonaMoralDao(ClientePMoralesDao personaMoralDao) {
		this.personaMoralDao = personaMoralDao;
	}

	/**
	 * @return the personaFisicaDao
	 */
	public ClientePersonasFisicasDao getPersonaFisicaDao() {
		return personaFisicaDao;
	}

	/**
	 * @param personaFisicaDao the personaFisicaDao to set
	 */
	public void setPersonaFisicaDao(ClientePersonasFisicasDao personaFisicaDao) {
		this.personaFisicaDao = personaFisicaDao;
	}

	/**
	 * @return the clienteDao
	 */
	public ClienteDao getClienteDao() {
		return clienteDao;
	}

	/**
	 * @param clienteDao the clienteDao to set
	 */
	public void setClienteDao(ClienteDao clienteDao) {
		this.clienteDao = clienteDao;
	}

	/**
	 * @return the rutaDao
	 */
	public RutaDao getRutaDao() {
		return rutaDao;
	}

	/**
	 * @param rutaDao the rutaDao to set
	 */
	public void setRutaDao(RutaDao rutaDao) {
		this.rutaDao = rutaDao;
	}

	/**
	 * @return the zonaDao
	 */
	public ZonaDao getZonaDao() {
		return zonaDao;
	}

	/**
	 * @param zonaDao the zonaDao to set
	 */
	public void setZonaDao(ZonaDao zonaDao) {
		this.zonaDao = zonaDao;
	}

	/**
	 * @return the municipiosDao
	 */
	public MunicipiosDao getMunicipiosDao() {
		return municipiosDao;
	}

	/**
	 * @param municipiosDao the municipiosDao to set
	 */
	public void setMunicipiosDao(MunicipiosDao municipiosDao) {
		this.municipiosDao = municipiosDao;
	}

	/**
	 * @return the delegacionDao
	 */
	public DelegacionDao getDelegacionDao() {
		return delegacionDao;
	}

	/**
	 * @param delegacionDao the delegacionDao to set
	 */
	public void setDelegacionDao(DelegacionDao delegacionDao) {
		this.delegacionDao = delegacionDao;
	}

	/**
	 * @return the estadosDao
	 */
	public EstadosDao getEstadosDao() {
		return estadosDao;
	}

	/**
	 * @param estadosDao the estadosDao to set
	 */
	public void setEstadosDao(EstadosDao estadosDao) {
		this.estadosDao = estadosDao;
	}

	/**
	 * @return the tipoZonaDao
	 */
	public TipoZonaDao getTipoZonaDao() {
		return tipoZonaDao;
	}

	/**
	 * @param tipoZonaDao the tipoZonaDao to set
	 */
	public void setTipoZonaDao(TipoZonaDao tipoZonaDao) {
		this.tipoZonaDao = tipoZonaDao;
	}

	
}
